using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using UniversalAdmin.Domain.Entities;


namespace UniversalAdmin.Infrastructure.Data.Contexts;

public class ApplicationDbContext : IdentityDbContext<User, Role, Guid>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
   : base(options) { }

    // 实体表映射到数据库(告诉数据库应该有哪些表)
    public DbSet<Menu> Menus => Set<Menu>();
    public DbSet<MenuRole> MenuRoles => Set<MenuRole>();
    public DbSet<Permission> Permissions => Set<Permission>();
    public DbSet<RolePermission> RolePermissions => Set<RolePermission>();
    public DbSet<SystemConfig> SystemConfigs => Set<SystemConfig>();
    public DbSet<OperationLog> OperationLogs => Set<OperationLog>();
    public DbSet<TokenBlacklist> TokenBlacklist => Set<TokenBlacklist>();
    public DbSet<Article> Articles => Set<Article>();
    public DbSet<ArticleCategory> ArticleCategories => Set<ArticleCategory>();


    //数据库表设计蓝图
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // 表名配置
        modelBuilder.Entity<User>().ToTable("users");
        modelBuilder.Entity<Role>().ToTable("roles");
        modelBuilder.Entity<Menu>().ToTable("menus");
        modelBuilder.Entity<Permission>().ToTable("permissions");
        modelBuilder.Entity<OperationLog>().ToTable("operating_logs");
        modelBuilder.Entity<SystemConfig>().ToTable("system_configs");
        modelBuilder.Entity<TokenBlacklist>().ToTable("token_blacklist");
        modelBuilder.Entity<Article>().ToTable("articles");
        modelBuilder.Entity<ArticleCategory>().ToTable("article_categories");

        modelBuilder.Entity<UserRole>()
            .HasKey(ur => new { ur.UserId, ur.RoleId });

        modelBuilder.Entity<RolePermission>()
            .HasKey(rp => new { rp.RoleId, rp.PermissionId });

        // 索引优化配置
        modelBuilder.Entity<Role>()
           .HasIndex(r => r.Name)
           .IsUnique();

        // 用户表配置 - 提升登录查询性能
        modelBuilder.Entity<User>(entity =>
        {
            // UserName字段索引（IdentityUser的字段），提升登录查询性能
            // 注意：IdentityUser默认已有UserName索引，这里确保唯一性
            entity.HasIndex(u => u.UserName)
                  .IsUnique()
                  .HasDatabaseName("IX_Users_UserName");

            // 自定义Username字段索引（如果需要保留这个字段）
            entity.HasIndex(u => u.Username)
                  .HasDatabaseName("IX_Users_Username_Custom");

            // 最后登录时间索引，用于统计查询
            entity.HasIndex(u => u.LastLoginAt)
                  .HasDatabaseName("IX_Users_LastLoginAt");

            // 锁定状态复合索引，提升锁定检查性能
            entity.HasIndex(u => new { u.LockoutEnd, u.LoginAttempts })
                  .HasDatabaseName("IX_Users_Lockout");

            // 状态索引，提升用户状态查询性能
            entity.HasIndex(u => u.Status)
                  .HasDatabaseName("IX_Users_Status");
        });

        // TokenBlacklist表配置
        modelBuilder.Entity<TokenBlacklist>(entity =>
        {
            // Token字段索引，提升黑名单查询性能
            entity.HasIndex(t => t.Token)
                  .HasDatabaseName("IX_TokenBlacklist_Token");

            // 过期时间索引，用于清理过期token
            entity.HasIndex(t => t.ExpireAt)
                  .HasDatabaseName("IX_TokenBlacklist_ExpireAt");
        });

        // 权限表配置
        modelBuilder.Entity<Permission>(entity =>
        {
            entity.HasKey(p => p.Id);
            entity.Property(p => p.Name).IsRequired().HasMaxLength(50);
            entity.Property(p => p.Description).HasMaxLength(200);
            entity.Property(p => p.Resource).IsRequired().HasMaxLength(50);
            entity.Property(p => p.Action).IsRequired().HasMaxLength(50);
            entity.Property(p => p.Type).IsRequired();
            entity.Property(p => p.SortOrder).IsRequired();
            entity.Property(p => p.IsEnabled).IsRequired();

            // 与角色的多对多关系
            entity.HasMany(p => p.RolePermissions)
                  .WithOne(rp => rp.Permission)
                  .HasForeignKey(rp => rp.PermissionId)
                  .OnDelete(DeleteBehavior.Cascade);
        });

        // 角色权限关系表配置
        modelBuilder.Entity<RolePermission>(entity =>
        {
            entity.ToTable("role_permissions");
            entity.HasKey(rp => new { rp.RoleId, rp.PermissionId });

            entity.HasOne(rp => rp.Role)
                  .WithMany(r => r.RolePermissions)
                  .HasForeignKey(rp => rp.RoleId)
                  .OnDelete(DeleteBehavior.Cascade);

            entity.HasOne(rp => rp.Permission)
                  .WithMany(p => p.RolePermissions)
                  .HasForeignKey(rp => rp.PermissionId)
                  .OnDelete(DeleteBehavior.Cascade);
        });

        // 显式中间实体 MenuRole
        modelBuilder.Entity<MenuRole>(mr =>
        {
            mr.ToTable("MenuRole");
            mr.HasKey(e => new { e.RoleId, e.MenuId });

            mr.HasOne(e => e.Role)
              .WithMany(r => r.MenuRoles)
              .HasForeignKey(e => e.RoleId);

            mr.HasOne(e => e.Menu)
              .WithMany(m => m.MenuRoles)
              .HasForeignKey(e => e.MenuId);
        });
    }
}


